package task.snake.model;

import java.awt.Point;
import java.util.LinkedList;

/**
 * The Creature class is the abstract class which describes general entity for
 * Snake and Frog.
 * 
 * @author Nadezhda Makarkina
 * 
 */
public abstract class Creature implements Runnable {
	private static Object lock = new Object();
	/**
	 * List of body's coordinates of creature.
	 */
	protected LinkedList<Point> body = new LinkedList<Point>();

	/**
	 * Snake model object.
	 */
	protected final SnakeModel sm;

	/**
	 * Field indicates if the thread has to be stopped.
	 */
	protected volatile boolean stopped;

	/**
	 * Pause between movements in milliseconds.
	 */
	protected long sleepTime;

	/**
	 * Constructs a new Creature object.
	 * 
	 * @param p
	 *            position on play field
	 * @param sm
	 *            snake model object
	 * @param sleepTime
	 *            speed of movement on play field
	 */
	public Creature(Point p, SnakeModel sm, long sleepTime) {
		body.add(p);
		this.sm = sm;
		this.sleepTime = sleepTime;
	}

	/**
	 * Moves creature on play field.
	 */
	protected abstract void move();

	/**
	 * Describe situation when creature clashes a wall, itself or another
	 * creature.
	 * 
	 * @param snake
	 * @return
	 */
	protected abstract boolean onClash(Snake snake);

	/**
	 * Returns location of creature's head on the play field.
	 * 
	 * @return
	 */
	public Point getHeadLocation() {
		return body.get(0);
	}

	/**
	 *  Sets the state of stopped field.
	 */
	public void setStopped() {
		stopped = true;
	}

	/**
	 * Runs object.
	 */
	public void run() {
		do {
			try {
				synchronized (lock) {
					move();
				}
				Thread.sleep(sleepTime);
			} catch (InterruptedException e) {
				stopped = true;
				e.printStackTrace();
			}
		} while (!stopped);
	}
}
